#!/usr/bin/env python3
###
# @Author: Logan.Li
# @Gitee: https://gitee.com/attacker
# @email: admin@attacker.club
# @Date: 2025-03-14 09:45:30
# @LastEditTime: 2025-03-14 09:45:35
# @Description: 华为云CCE监控模块
###

import logging
from typing import Dict, List
from huaweicloud_sdk_cce.v3 import *
from huaweicloud_sdk_cce.v3.region.cce_region import CceRegion
from ..core import HuaweiCloudMonitor

class CCEMonitor(HuaweiCloudMonitor):
    """CCE监控类"""
    
    def __init__(self, config: Dict):
        super().__init__(config)
        self.namespace = "SYS.CCE"
        self.cce_client = CceClient.new_builder() \
            .with_credentials(self.credentials) \
            .with_region(CceRegion.value_of(config['region'])) \
            .build()
            
    def list_clusters(self) -> List[Dict]:
        """获取所有CCE集群"""
        try:
            request = ListClustersRequest()
            response = self.cce_client.list_clusters(request)
            return response.to_dict().get('items', [])
        except Exception as e:
            logging.error(f"获取CCE集群列表失败: {e}")
            return []
            
    def list_nodes(self, cluster_id: str) -> List[Dict]:
        """获取集群节点列表
        
        Args:
            cluster_id: 集群ID
        """
        try:
            request = ListNodesRequest()
            request.cluster_id = cluster_id
            response = self.cce_client.list_nodes(request)
            return response.to_dict().get('items', [])
        except Exception as e:
            logging.error(f"获取节点列表失败: {e}")
            return []
            
    def get_node_metrics(self, cluster_id: str, node_id: str) -> Dict:
        """获取节点监控指标
        
        Args:
            cluster_id: 集群ID
            node_id: 节点ID
        """
        dimensions = [{
            "name": "cluster_id",
            "value": cluster_id
        }, {
            "name": "node_id",
            "value": node_id
        }]
        
        metrics = {}
        metric_list = [
            ("cpu_usage", "CPU使用率"),
            ("memory_usage", "内存使用率"),
            ("disk_usage_rate", "磁盘使用率"),
            ("gpu_usage", "GPU使用率"),
            ("pod_count", "Pod数量")
        ]
        
        for metric_name, metric_desc in metric_list:
            data = self.get_metric_data(
                namespace=self.namespace,
                metric_name=metric_name,
                dimensions=dimensions
            )
            metrics[metric_desc] = data
            
        return metrics
        
    def monitor_all_clusters(self) -> Dict:
        """监控所有CCE集群"""
        clusters = self.list_clusters()
        result = {
            'total_clusters': len(clusters),
            'abnormal_nodes': [],
            'cluster_status': []
        }
        
        for cluster in clusters:
            cluster_id = cluster['metadata']['uid']
            cluster_name = cluster['metadata']['name']
            cluster_status = cluster['status']['phase']
            
            # 记录集群状态
            result['cluster_status'].append({
                'id': cluster_id,
                'name': cluster_name,
                'status': cluster_status
            })
            
            # 如果集群不是正常状态，跳过节点监控
            if cluster_status != 'Available':
                continue
            
            # 获取集群节点
            nodes = self.list_nodes(cluster_id)
            for node in nodes:
                node_id = node['metadata']['uid']
                node_name = node['metadata']['name']
                
                # 获取节点指标
                metrics = self.get_node_metrics(cluster_id, node_id)
                
                # 检查异常指标
                for metric_name, data in metrics.items():
                    if not data:
                        continue
                        
                    datapoints = data.get('datapoints', [])
                    if not datapoints:
                        continue
                        
                    latest = datapoints[-1]
                    value = latest.get('average')
                    
                    # 判断异常条件
                    is_abnormal = False
                    if metric_name == "CPU使用率" and value > 80:
                        is_abnormal = True
                    elif metric_name == "内存使用率" and value > 85:
                        is_abnormal = True
                    elif metric_name == "磁盘使用率" and value > 90:
                        is_abnormal = True
                    elif metric_name == "GPU使用率" and value > 90:
                        is_abnormal = True
                    
                    if is_abnormal:
                        result['abnormal_nodes'].append({
                            'cluster': cluster_name,
                            'node': node_name,
                            'metric': metric_name,
                            'value': value,
                            'time': latest.get('timestamp')
                        })
        
        # 只保留最异常的前5个节点
        result['abnormal_nodes'] = sorted(
            result['abnormal_nodes'],
            key=lambda x: x['value'],
            reverse=True
        )[:5]
        
        return result
